package model

import (
	"errors"
	"io/ioutil"
	"math/rand"
	"net"
	"net/http"
	"os"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"
)

//机器信息 使用缓存
func CreateMacInfo() MacInfo {
	MacInfo := MacInfo{}
	MacInfo.TYPE = 0
	if len(MacInfoCache) > 0 {
		MacInfo.CPUNUM = MacInfoCache["CPUNUM"].(int)
		MacInfo.GOOS = MacInfoCache["GOOS"].(string)
		MacInfo.GOARCH = MacInfoCache["GOARCH"].(string)
		MacInfo.HOSTNAME = MacInfoCache["HOSTNAME"].(string)
		MacInfo.PUBLICIP = MacInfoCache["PUBLICIP"].(string)
		MacInfo.PUBLICERR = MacInfoCache["PUBLICERR"].(string)
	} else {
		MacInfo.CPUNUM = runtime.GOMAXPROCS(0)
		MacInfo.GOOS = runtime.GOOS
		MacInfo.GOARCH = runtime.GOARCH
		name, err := os.Hostname()
		if err != nil {
			name = "未知"
		}

		publicIp, Publicerr := GetLocalPublicIp()
		MacInfo.PUBLICIP = publicIp
		MacInfo.PUBLICERR = Publicerr

		MacInfo.HOSTNAME = name
		MacInfoCache["CPUNUM"] = MacInfo.CPUNUM
		MacInfoCache["GOOS"] = MacInfo.GOOS
		MacInfoCache["GOARCH"] = MacInfo.GOARCH
		MacInfoCache["HOSTNAME"] = MacInfo.HOSTNAME
		MacInfoCache["PUBLICIP"] = MacInfo.PUBLICIP
		MacInfoCache["PUBLICERR"] = MacInfo.PUBLICERR
	}

	if MacInfo.PUBLICIP == "" {
		publicIp, Publicerr := GetLocalPublicIp()
		MacInfo.PUBLICIP = publicIp
		MacInfo.PUBLICERR = Publicerr
		MacInfoCache["PUBLICIP"] = MacInfo.PUBLICIP
		MacInfoCache["PUBLICERR"] = MacInfo.PUBLICERR
	}

	MacInfo.TESTSPEED = showspeed()

	MacInfo.OffOlineLog = make(map[string]map[string]map[string]string)
	OffOlineLog, err := ioutil.ReadFile("OffOnline.log")
	if err == nil && string(OffOlineLog) != "" {
		data := make(map[string]map[string]map[string]string)
		line := strings.Split(string(OffOlineLog), "\n")
		for _, v := range line {
			if v != "" {
				fields := strings.Split(v, "|")
				key := strings.TrimSpace(fields[1]) //remoteIP

				if _, ok := data[key]; !ok {
					data[key] = make(map[string]map[string]string)
				}
				if _, ok := data[key][IntranetIp]; !ok {
					data[key][IntranetIp] = make(map[string]string)
				}

				data[key][IntranetIp]["time"] += strings.TrimSpace(fields[0]) + "|"
			}
		}
		MacInfo.OffOlineLog = data
	}

	/*	MacInfo.OffOlineLog = make(map[string]map[string]string)
		OffOlineLog,err := ioutil.ReadFile("OffOnline.log")
		IntranetIp = "192.168.0."+strconv.Itoa(rand.Intn(10))
		if err == nil && string(OffOlineLog) != ""{
			data := make(map[string]map[string]string)
			data[IntranetIp] = make(map[string]string) //本机IP
			line := strings.Split(string(OffOlineLog),"\n")
			for _,v := range line{
				if v != ""{
					fields := strings.Split(v,"|")
					data[IntranetIp]["time"] = strings.TrimSpace(fields[0])
					data[IntranetIp]["remoteIp"] = strings.TrimSpace(fields[1])
					//data[IntranetIp]["FailNum"] = strings.TrimSpace(fields[3])
				}
			}
			fmt.Println(data)
			MacInfo.OffOlineLog = data
		}*/
	return MacInfo
}

//获取公网IP
func GetLocalPublicIp() (string, string) {
	client := &http.Client{
		Timeout: 3 * time.Second,
	}
	resp, err := client.Get("http://myexternalip.com/raw")
	if err != nil {
		return "", err.Error()
	}
	defer resp.Body.Close()
	content, _ := ioutil.ReadAll(resp.Body)
	return string(content), ""
}

//网速测试
func showspeed() string {
	client := &http.Client{
		Timeout: 3 * time.Second,
	}
	stime := time.Now().UnixNano() / 1e6
	rand.Seed(time.Now().UnixNano())
	imgUrl := "http://i0.sinaimg.cn/ent/y/w/2008-11-24/U1513P28T52D3414F872DT20081124143718.jpg?id=" + strconv.Itoa(rand.Intn(8))
	fs := 410.45 * 1000
	resp, err := client.Get(imgUrl)
	if err != nil {
		return ""
	}
	defer resp.Body.Close()
	etime := time.Now().UnixNano() / 1e6
	iKBps := int64(fs) / (etime - stime) //文件大小 / 耗时 = 每毫秒下载大小
	iKbps := iKBps * 8
	//dspeed := math.Ceil(float64(alltime*1000))/1000
	dspeed := iKBps
	dspeedStr := "当前的网速为：" + strconv.Itoa(int(iKbps)) + " Kbps；下载速度为：" + strconv.Itoa(int(iKBps)) + " K/秒 "
	if dspeed < 0 {
		dspeedStr += ""
	} else if dspeed <= 128 {
		dspeedStr += "在512K到1M之间"
	} else if dspeed <= 256 {
		dspeedStr += "在1M到2M之间"
	} else if dspeed <= 512 {
		dspeedStr += "在2M到4M之间"
	} else if dspeed <= 768 {
		dspeedStr += "在4M到6M之间"
	} else if dspeed <= 1024 {
		dspeedStr += "在6M到8M之间"
	} else if dspeed <= 1280 {
		dspeedStr += "在8M到10M之间"
	} else if dspeed <= 1536 {
		dspeedStr += "在10M到12M之间"
	} else if dspeed <= 2560 {
		dspeedStr += "在12M到20M之间"
	} else if dspeed <= 12800 {
		dspeedStr += "在20M到100M之间"
	} else {
		dspeedStr += "超过了100M专线"
	}
	return dspeedStr
}

//端口测试
func TestPort(ipv4, port string) (map[string]string, error) {
	res := make(map[string]string)
	address := net.ParseIP(ipv4)
	if address == nil {
		return res, errors.New("IP 格式错误")
	} else {
		var wg sync.WaitGroup
		client := &http.Client{
			Timeout: 3 * time.Second,
		}
		_port := strings.Split(port, ",")
		for _, v := range _port {
			res[v] = "关闭"
			wg.Add(1)
			go func(v string) {
				//url := "http://192.168.111.134:" + v
				url := "http://" + address.String() + ":" + v
				resp, err := client.Get(url)
				if (err == nil) && resp.StatusCode == 200 {
					res[v] = "打开"
				}
				if resp != nil {
					remoteIp := resp.Header.Get("remoteIp")
					if remoteIp != "" {
						res[v] += " 内网IP: " + remoteIp
					} else {
						res[v] = "占用"
					}
				}
				wg.Done()
			}(v)
		}
		wg.Wait()
		return res, nil
	}
}

//获取内网IP
func GetIntranetIp() string {
	addrs, _ := net.InterfaceAddrs()
	for _, address := range addrs {
		// 检查ip地址判断是否回环地址
		if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
			if ipnet.IP.To4() != nil {
				return ipnet.IP.String()
			}
		}
	}
	return ""
}
